<?php
// +----------------------------------------------------------------------
// | A3Mall
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.a3-mall.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: xzncit <158373108@qq.com>
// +----------------------------------------------------------------------

namespace app\common\model\users;

use app\admin\controller\Auth;
use app\common\model\base\A3Mall;
use http\Client\Curl\User;
use mall\utils\Tool;
use think\facade\Request;

class UsersLog extends A3Mall{

    /**
     * 用户日志类型
     */
    const TYPE_LIST = [

        'LOGIN' => [    // 登录成功
            'type'  => 1,
            'format'    => [
                ['登录成功：用户 [ %s ]',['username']]
            ],
        ],

        'LOGIN_OUT' => [    // 申请退出
            'type'  => 2,
            'format'    => [
                ['退出成功',[]]
            ],
        ],


        'RULE_UPDATE' => [    // 更新规则
            'type'  => 3,
            'format'    => [
                ['策略设置更新：新参数[ %s ]',['params']]
            ],
            'request'   => 'post',
            'class' => 'coin/CoinRule',   //关联ID对应的类
        ],

        'RULE_UPDATE_TYPE_OR_OPEN' => [    // 更改策略类型或开关
            'type'  => 3,
            'format'    => [
                ['策略类型及开关更新：新参数[ %s ]',['params']]
            ],
            'request'   => 'post',
            'class' => 'coin/CoinRule',   //关联ID对应的类
        ],

        'COVER_ORDER' => [    // 补仓
            'type'  => 4,
            'format'    => [
                ['补仓：请求参数[ %s ]',['params']]
            ],
            'request'   => 'post',
            'class' => 'coin/CoinRule',   //关联ID对应的类
        ],

        'CLEARANCE_ORDER' => [    // 清仓
            'type'  => 5,
            'format'    => [
                ['清仓：请求参数[ %s ]',['params']]
            ],
            'request'   => 'post',
            'class' => 'coin/CoinRule',   //关联ID对应的类
        ],


    ];

    protected $name = "users_log";

    protected $type = [
        "id"=>"integer",
        "user_id"=>"integer",
        "type"=>"integer",
        "time"=>"integer"
    ];

    /**
     * 添加日志
     * @param string $type 类型字符串
     * @param $messageList 添加的信息
     * @param int|null $relationId
     * @return bool
     */
    static function logAdd(string $type,$messageParams,int $relationId = null){

        $logData = [
            'relation_id'   => is_null($relationId)?0:$relationId,
            'ip'    => self::getIp(),
            'time'  => time(),

        ];
        // 判断类型是否存在
        list($logData['type'],$logData['intro']) = self::getTypeAndMessage($type,$messageParams);
        try {
            $userId = \mall\basic\Users::get('id');
            $logData['user_id'] = is_null($userId)?0:$userId;
            // 插入数据
            self::insert($logData);
        }catch (\Exception $e) {
            return false;
        }
    }

    /**
     * 获取类型及信息
     * @param string $type 类型
     * @param $messageParams 信息
     * @return array [类型，信息]
     * @throws \Exception
     */
    static function getTypeAndMessage(string $type,$messageParams) {
        // 获取所有类型
        $typeList = self::TYPE_LIST;

        if(!array_key_exists($type,$typeList)) {
            throw new \Exception('Error type ' . $type . ' does not exist');
        }
        $typeFormat = $typeList[$type];
        // 获取message 信息
        $message = [
            'message'   => [],
        ];

        if(array_key_exists('format',$typeFormat) && is_array($typeFormat['format'])) {
            $messageParams = is_array($messageParams)?$messageParams:[];
            // 格式化信息
            $messageList = [];
            foreach($typeFormat['format'] as $format) {
                 $params = [$format[0]];
                 foreach($format[1] as $key) {
                     $params[] = array_key_exists($key,$messageParams)?$messageParams[$key]:'';
                 }
                 // 獲取格式化后的數據
                 $messageList[] = call_user_func_array('sprintf',$params);
            }
            switch (count($messageList)) {
                case 0:
                    $message['message'] = null;
                    break;
                case 1:
                    $message['message'] = $messageList[0];
                    break;
                default:
                    $message['message'] = $messageList;
            }
        } else {
            $message['message'] = $messageParams;
        }

        // 判断是否需要存储请求信息
        if(array_key_exists('request',$typeFormat) && in_array($typeFormat['request'],['get','post'])) {
            $message['request'] = [];
            switch ($typeFormat['request']) {
                case 'get':
                    $message['request'] = Request::get();
                    break;
                case 'post':
                    $message['request'] = Request::post();
                    break;
            }
        }
        return [$typeFormat['type'],self::encode($message)];
    }

    /**
     * 获取客户端IP
     */
    static function getIp() {
        $ip = Request::ip();
        $realIpField = 'HTTP_X_REAL_IP';
        if(array_key_exists($realIpField,$_SERVER) && is_string($_SERVER[$realIpField]) && Request::isValidIP($_SERVER[$realIpField])) {
            $ip = $_SERVER[$realIpField];
        }
        return $ip;
    }

    /**
     * 对信息进行序列化处理
     * @param $params
     * @return string
     */
    static function encode($params) {
        return serialize($params);
    }

    /**
     * 对序列化后的信息进行反系列化处理
     * @param string $encodeStr
     * @return mixed
     */
    static function decode(string $encodeStr) {
        return unserialize($encodeStr);
    }

    public function getList($condition=[],$size=10){
        $count = $this->where($condition)->count();
        $data = $this->where($condition)->order("id","DESC")->paginate($size);

        return [
            "count"=>$count,
            "data"=>$data->items()
        ];
    }

    public function setIntroAttr($value){
        return Tool::editor($value);
    }

    public function setIpAttr($value){
        return strip_tags(trim($value));
    }

    public function getTimeAttr($value){
        return date("Y-m-d H:i:s",$value);
    }
}